package com.jiangjiang.eshop.wms.stock;

import com.google.common.collect.Sets;
import com.jiangjiang.eshop.order.dto.OrderItemDTO;
import com.jiangjiang.eshop.schedule.dto.SaleDeliveryScheduleResult;
import com.jiangjiang.eshop.schedule.dto.ScheduleOrderSendOutDetailDTO;
import com.jiangjiang.eshop.wms.domain.WmsGoodsAllocationStock;
import com.jiangjiang.eshop.wms.domain.WmsGoodsAllocationStockDetail;
import com.jiangjiang.eshop.wms.domain.WmsGoodsStock;
import com.jiangjiang.eshop.wms.service.WmsGoodsAllocationStockDetailService;
import com.jiangjiang.eshop.wms.service.WmsGoodsAllocationStockService;
import com.jiangjiang.eshop.wms.service.WmsGoodsStockService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @Author Jianghaowen
 * @Date 2021/9/14
 * @Description: TODO
 * @Version V1.0
 **/
@Component
public class PayOrderWmsStockUpdater extends AbstractWmsStockUpdater{

    /**
     * 调度结果
     */
    private SaleDeliveryScheduleResult scheduleResult;

    @Autowired
    private WmsGoodsStockService goodsStockService;
    @Autowired
    private WmsGoodsAllocationStockService goodsAllocationStockService;
    @Autowired
    private WmsGoodsAllocationStockDetailService goodsAllocationStockDetailService;


    @Override
    protected void updateGoodsStock() {
        OrderItemDTO orderItem = scheduleResult.getOrderItem();
        WmsGoodsStock wmsGoodsStock = goodsStockService.queryBySkuIds(Sets.newHashSet(orderItem.getGoodsSkuId())).get(0);
        wmsGoodsStock.setLockedStockQuantity(wmsGoodsStock.getLockedStockQuantity() - orderItem.getPurchaseQuantity());
        wmsGoodsStock.setOutputStockQuantity(wmsGoodsStock.getOutputStockQuantity() + orderItem.getPurchaseQuantity());
        goodsStockService.updateById(wmsGoodsStock);
    }


    @Override
    protected void updateGoodsAllocationStock() {
        OrderItemDTO orderItem = scheduleResult.getOrderItem();
        Map<Long, WmsGoodsAllocationStock> stockMap = goodsAllocationStockService.queryBySkuId(orderItem.getGoodsSkuId())
                .stream()
                .collect(Collectors.toMap(WmsGoodsAllocationStock::getGoodsAllocationId, Function.identity()));

        List<WmsGoodsAllocationStock> allocationStocks = scheduleResult.getPickingItems().stream().map(pickingItem -> {
            WmsGoodsAllocationStock stock = stockMap.get(pickingItem.getGoodsAllocationId());
            stock.setLockedStockQuantity(stock.getLockedStockQuantity() - pickingItem.getPickingCount());
            stock.setOutputStockQuantity(stock.getOutputStockQuantity() + pickingItem.getPickingCount());
            return stock;
        }).collect(Collectors.toList());

        goodsAllocationStockService.updateBatchById(allocationStocks);
    }



    @Override
    protected void updateGoodsAllocationStockDetail() throws Exception {
        List<Long> detailIds = scheduleResult.getSendOutDetails()
                .stream()
                .map(ScheduleOrderSendOutDetailDTO::getGoodsAllocationStockDetailId)
                .collect(Collectors.toList());

        Map<Long, WmsGoodsAllocationStockDetail> stockDetailMap = goodsAllocationStockDetailService.queryByIds(detailIds)
                .stream()
                .collect(Collectors.toMap(WmsGoodsAllocationStockDetail::getId, Function.identity()));

        List<WmsGoodsAllocationStockDetail> stockDetails = scheduleResult.getSendOutDetails().stream().map(sendOutDetail -> {
            WmsGoodsAllocationStockDetail stockDetail = stockDetailMap.get(sendOutDetail.getGoodsAllocationStockDetailId());
            stockDetail.setLockedStockQuantity(stockDetail.getLockedStockQuantity() - sendOutDetail.getSendOutCount());
            return stockDetail;
        }).collect(Collectors.toList());

        goodsAllocationStockDetailService.updateBatchById(stockDetails);
    }

    @Override
    public void setParameter(Object parameter) {
        this.scheduleResult = (SaleDeliveryScheduleResult) parameter;
    }
}
